import 'dart:math';

import 'package:flutter/material.dart';
import 'package:flutter_application/app/app_color.dart';

// 画板
class CanvasPage extends StatefulWidget {
  const CanvasPage({super.key});

  @override
  State<CanvasPage> createState() => _CanvasPageState();
}

class _CanvasPageState extends State<CanvasPage> {
  Color _color = Colors.black;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('画板'),
      ),
      body: CustomPaint(
        painter: CanvasView(context, _color),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _changeColor,
        child: const Icon(Icons.add),
      ),
    );
  }

  void _changeColor() {
    setState(() {
      _color = AppColor.randomColor();
    });
  }
}

class CanvasView extends CustomPainter {
  late Paint mHelpPaint;
  late Color color;
  BuildContext context;

  //接收context,初始化画笔
  CanvasView(this.context, this.color) {
    mHelpPaint = Paint();
    mHelpPaint.style = PaintingStyle.stroke;
    mHelpPaint.isAntiAlias = true;
  }

  @override
  void paint(Canvas canvas, Size size) {
    //九宫格
    var winSize = MediaQuery.of(context).size;
    mHelpPaint.style = PaintingStyle.stroke;
    mHelpPaint.color = const Color(0xffBBC3C5);
    canvas.drawPath(gridPath(20, winSize), mHelpPaint);

    // canvas.drawPath(drawCoo(canvas, Size(winSize.width/2, winSize.height/2),winSize), mHelpPaint);

    //绘制n角星
    canvas.translate(0, 320);

    canvas.save(); 

    mHelpPaint.style = PaintingStyle.fill;
    mHelpPaint.color = color;
    for (int i = 5; i < 10; i++) {
      canvas.translate(64, 0);
      canvas.drawPath(nStarPath(i, 30, 15), mHelpPaint);
    }
    canvas.restore();

    canvas.translate(0, 70);
    canvas.save(); //绘制正n角星
    for (int i = 5; i < 10; i++) {
      canvas.translate(64, 0);
      canvas.drawPath(regularStarPath(i, 30), mHelpPaint);
    }
    canvas.restore();

    canvas.translate(0, 70);
    canvas.save(); //绘制正n边形
    for (int i = 5; i < 10; i++) {
      canvas.translate(64, 0);
      canvas.drawPath(regularPolygonPath(i, 30), mHelpPaint);
    }
    canvas.restore();
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    return true;
  }

  /*
  绘制网格路径
  @param step    小正方形边长
  @param winSize 屏幕尺寸
  */
  Path gridPath(int step, Size winSize) {
    Path path = Path();

    for (int i = 0; i < winSize.height / step + 1; i++) {
      path.moveTo(0, step * i.toDouble());
      path.lineTo(winSize.width, step * i.toDouble());
    }

    for (int i = 0; i < winSize.width / step + 1; i++) {
      path.moveTo(step * i.toDouble(), 0);
      path.lineTo(step * i.toDouble(), winSize.height);
    }
    return path;
  }

  //绘制坐标系
  drawCoo(Canvas canvas, Size coo, Size winSize) {
    //初始化网格画笔
    Paint paint = Paint();
    paint.strokeWidth = 2;
    paint.style = PaintingStyle.stroke;

    //绘制直线
    canvas.drawPath(cooPath(coo, winSize), paint);
    //左箭头
    canvas.drawLine(Offset(winSize.width, coo.height),
        Offset(winSize.width - 10, coo.height - 6), paint);
    canvas.drawLine(Offset(winSize.width, coo.height),
        Offset(winSize.width - 10, coo.height + 6), paint);
    //下箭头
    canvas.drawLine(Offset(coo.width, winSize.height - 90),
        Offset(coo.width - 6, winSize.height - 10 - 90), paint);
    canvas.drawLine(Offset(coo.width, winSize.height - 90),
        Offset(coo.width + 6, winSize.height - 10 - 90), paint);
  }

  /*
  坐标系路径 

  @param coo     坐标点
  @param winSize 屏幕尺寸
  @return 坐标系路径
  */
  Path cooPath(Size coo, Size winSize) {
    Path path = Path();
    //x正半轴线
    path.moveTo(coo.width, coo.height);
    path.lineTo(winSize.width, coo.height);
    //x负半轴线
    path.moveTo(coo.width, coo.height);
    path.lineTo(coo.width - winSize.width, coo.height);
    //y负半轴线
    path.moveTo(coo.width, coo.height);
    path.lineTo(coo.width, coo.height - winSize.height);
    //y负半轴线
    path.moveTo(coo.width, coo.height);
    path.lineTo(coo.width, winSize.height);
    return path;
  }

  /*
 n角星路径
 
 @param num 几角星
 @param R   外接圆半径
 @param r   内接圆半径
 @return n角星路径
 */
  Path nStarPath(int num, double R, double r) {
    Path path = Path();
    double perDeg = 360 / num; //尖角的度数
    double degA = perDeg / 2 / 2;
    double degB = 360 / (num - 1) / 2 - degA / 2 + degA;

    path.moveTo(cos(_rad(degA)) * R, (-sin(_rad(degA)) * R));
    for (int i = 0; i < num; i++) {
      path.lineTo(
          cos(_rad(degA + perDeg * i)) * R, -sin(_rad(degA + perDeg * i)) * R);
      path.lineTo(
          cos(_rad(degB + perDeg * i)) * r, -sin(_rad(degB + perDeg * i)) * r);
    }
    path.close();
    return path;
  }

  double _rad(double deg) {
    return deg * pi / 180;
  }

  /*
 * 画正n角星的路径:
 *
 * @param num 角数
 * @param R   外接圆半径
 * @return 画正n角星的路径
 */
  Path regularStarPath(int num, double R) {
    double degA, degB;
    if (num % 2 == 1) {
      //奇数和偶数角区别对待
      degA = 360 / num / 2 / 2;
      degB = 180 - degA - 360 / num / 2;
    } else {
      degA = 360 / num / 2;
      degB = 180 - degA - 360 / num / 2;
    }
    double r = R * sin(_rad(degA)) / sin(_rad(degB));
    return nStarPath(num, R, r);
  }

/*
 * 画正n边形的路径
 *
 * @param num 边数
 * @param R   外接圆半径
 * @return 画正n边形的路径
 */
  Path regularPolygonPath(int num, double R) {
    double r = R * cos(_rad(360 / num / 2)); //!!一点解决
    return nStarPath(num, R, r);
  }
}